<template>
  <el-card class="box-card basic-table" :class="{'only-table': onlyTable}">
    <VisibleModal v-if="columnSetVisible" :visible.sync="columnSetVisible" :columns="defaultColumnsVisible" title="自定义列" @submit="setVisible" />
    <div slot="header" v-if="!onlyTable" style="position: relative">

      <div class="head-text">
        <slot name="title">

          <el-tabs v-if="tabs.length > 0" v-model="activeName" @tab-click="handleTabClick">
            <el-tab-pane v-for="(item, index) in tabs" :key="index" :label="item.label" :name="'tab-' + index"></el-tab-pane>
          </el-tabs>

          <span v-else>
            {{ title }}
          </span>
        </slot>
        <small>
          <slot name="tips"></slot>
        </small>
      </div>
      <div class="button-group">
        <slot name="beforeButtons"></slot>
        <template v-if="showButtonGroup">
          <el-button-group>
            <el-button plain @click="excel">excel导出</el-button>
            <el-button plain @click="columnSetVisible = true">字段筛选</el-button>
            <el-button plain @click="copy">拷贝</el-button>
          </el-button-group>

          <!--<el-dropdown ref="copyBtn" trigger="click" split-button type="primary" @click="copy">
            copy
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item command="header" @click.native="copy($event, false)">无表头</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>-->
        </template>
        <slot name="buttons"></slot>
      </div>
      <div class="clearfix"></div>
    </div>

    <slot name="search"></slot>

    <el-table
      v-loading="listLoading"
      ref="elTable"
      :key="tableHash"
      :data="list"
      size="mini"
      stripe
      border
      show-overflow-tooltip
      :show-summary="showSummary"
      :summary-method="getSummaries"
      @selection-change="handleSelectionChange"
    >
      <el-table-column v-if="selection" type="selection" width="35"/>

      <el-table-column v-if="sequence" type="index" width="35"/>

      <slot name="preColumn"></slot>

      <el-table-column v-for="(item) in columnsVisible" v-if="item.visible" :key="item.data" :min-width="item.minWidth" :width="item.width" :label="item.label" :prop="item.data" :fixed="item.fixed" align="center">
        <template slot-scope="scope">
          <span>{{ getColumnsData(item, scope) }}</span>
        </template>
      </el-table-column>

      <slot name="column"/>
    </el-table>

    <div v-if="page" class="pagination-container pull-right">
      <Pagination
        :totalItem="total"
        :perItem="listQuery.pageSize"
        :page="listQuery.pageNum"
        @pagination="handleCurrentChange"
        @sizeChange="handleSizeChange"
      />
    </div>
    <div class="clearfix"></div>
  </el-card>
</template>

<script>
import Pagination from '@/components/Pagination'
import {httpGetTable} from '@/utils/ajax'
import {merge, alert, copy} from '@/utils'
import VisibleModal from './VisibleModal'
import md5 from 'md5'
import store from 'store'
import $ from 'jquery'
export default {
  components: {
    Pagination,
    VisibleModal
  },
  props: {
    // 请求地址
    url: {
      type: String,
      default: ''
    },
    // 暂时列
    columns: {
      type: Array,
      default() {
        return []
      }
    },
    // 标签页
    tabs: {
      type: Array,
      default() {
        return []
      }
    },
    // 标题
    title: {
      type: String,
      default: '列表'
    },
    // 只包含表格
    onlyTable: {
      type: Boolean,
      default: false
    },
    // 分页
    initParams: {
      type: Object,
      default() {
        return {}
      }
    },
    // 是否包含分页功能
    page: {
      type: Boolean,
      default: true
    },
    // 默认请求接口
    createGet: {
      type: Boolean,
      default: true
    },
    // 复选框
    selection: {
      type: Boolean,
      default: true
    },
    // 序列号
    sequence: {
      type: Boolean,
      default: false
    },
    // 求和的方法
    getSummaries: {
      type: [Function],
      default: () => {}
    },
    showSummary: {
      type: Boolean,
      default: false
    },
    showButtonGroup: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      list: [],
      total: 0,
      listLoading: false,
      downloadLoading: false,
      listQuery: {
        pageNum: 1,
        pageSize: 20
      },
      columnSetVisible: false,
      fullPath: this.$route.fullPath,
      innerColumnsVisible: '',
      multipleSelection: [],
      activeName: '',
      innerColumns: this.columns,
      tabUrl: '',
      checkData: []
    }
  },
  computed: {
    // 那些数据需要重新修改
    whichColumnRender() {
      const temp = {}
      if (Array.isArray(this.innerColumns)) {
        this.innerColumns.forEach(v => {
          if (this.$_.isFunction(v.render)) {
            temp[v.data] = v.render
          }
        })
      }
      return temp
    },
    // excelHeader
    excelHeader() {
      const temp = []
      if (Array.isArray(this.innerColumns)) {
        this.innerColumns.forEach(v => {
          temp.push(v.label)
        })
      }
      return temp
    },
    hash() {
      return md5(this.fullPath) + '_table'
    },
    tableHash() {
      return md5(JSON.stringify(this.columnsVisibleStore))
    },
    columnsVisibleStore() {
      return this.innerColumnsVisible || store.get(this.hash) || {}
    },
    columnsVisible() {
      const columnsVisible = this.columnsVisibleStore
      this.innerColumns.forEach(v => {
        const visible = columnsVisible && columnsVisible[v.data] !== undefined ? columnsVisible[v.data] : true
        this.$set(v, 'visible', visible)
      })
      return this.innerColumns.map(v => {
        if (!v.width && !v.minWidth) {
          v.minWidth = '120px'
        }
        return v
      })
    },
    defaultColumnsVisible() {
      const temp = []
      this.columnsVisible.forEach(v => {
        temp.push({
          visible: v.visible,
          label: v.label,
          data: v.data
        })
      })
      return temp
    },
    // 是否展示excel copy 等内置button
    showButtons() {
      return true
    },
    // 真实的url
    innerUrl() {
      return this.tabUrl || this.url
    }
  },
  created() {
    if (this.createGet) {
      // 是否有tabs 如果有调用一下
      if (Array.isArray(this.tabs) && this.tabs.length > 0) {
        let flag = true
        for (const k in this.tabs) {
          const v = this.tabs[k]
          if (v.default) {
            this.handleTabClick(parseInt(k), true)
            flag = false
            continue
          }
        }
        if (flag) {
          this.handleTabClick(0, true)
        }
      } else {
        this.getList()
      }
    }
  },
  methods: {
    // 获取list
    getList() {
      if (this.innerUrl) {
        const params = merge(this.listQuery, this.initParams)
        let p = ''
        if (this.page) {
          p = httpGetTable
        } else {
          p = this.$ajax.get
        }
        if (p) {
          this.listLoading = true
          return p(this.innerUrl, params).then(response => {
            if (response.success) {
              this.list = response.data
              this.$emit('setList', this.list)
              if (this.page) {
                this.total = response.totalItem
                this.$emit('setTotalItem', this.total)
              }
            }
          }).finally(_ => {
            this.listLoading = false
          })
        }
      } else {
        alert('请求地址未配置')
      }
      return Promise.resolve(true)
    },
    // 分页大小变化
    handleSizeChange(val) {
      this.listQuery.pageSize = val
      this.getList()
    },
    // 切换页数
    handleCurrentChange(val) {
      this.listQuery.pageNum = val
      this.getList()
    },
    // 搜索
    search(params = {}) {
      this.listQuery = merge(this.listQuery, params)
      return this.getList()
    },
    // columnsData
    getColumnsData(column, scope) {
      if (this.$_.isFunction(column.render)) {
        return column.render(scope.row[column.data], scope.row, scope)
      } else {
        return scope.row[column.data]
      }
    },
    // getTableData 下载excel 用
    getTableData() {
      const table = this.$refs.elTable.$el.querySelector('.el-table__body-wrapper').querySelector('table')
      const rows = table.querySelectorAll('tr')
      return this.getCellData(rows)
    },
    // 获取单元格数据
    getCellData(rows, cellType = 'td') {
      const data = []
      for (let i = 0; i < rows.length; i++) {
        const row = rows[i]
        const tds = $(row).find(cellType)
        const item = []
        for (let j = 0; j < tds.length; j++) {
          const td = tds[j]
          if (j === 0) {
            if (td.textContent) {
              item.push($.trim(td.textContent || td.innerText))
            }
          } else {
            item.push($.trim(td.textContent || td.innerText))
          }
        }
        data.push(item)
      }
      return data
    },
    // 为复制准备的获取数据方法
    getSelectTrDataOrAll() {
      const table = this.$refs.elTable.$el.querySelector('.el-table__body-wrapper').querySelector('table')
      const checkBoxs = table.querySelectorAll('.el-checkbox.is-checked')
      if (checkBoxs.length) {
        const rows = []
        for (let i = 0; i < checkBoxs.length; i++) {
          const node = checkBoxs[i]
          rows.push($(node).closest('tr'))
        }
        return this.getCellData(rows)
      }
      return this.getTableData()
    },
    // 获取excel 的head 头 下载excel 用
    getTableHead() {
      const table = this.$refs.elTable.$el.querySelector('.el-table__header-wrapper').querySelector('table')
      const rows = table.querySelectorAll('tr')
      const data = this.getCellData(rows, 'th')
      if (Array.isArray(data) && data[0]) {
        return data[0]
      }
      return []
    },
    // excel 下载
    excel() {
      this.downloadLoading = true
      import('@/vendor/Export2Excel').then(excel => {
        excel.export_json_to_excel({
          header: this.getTableHead(),
          data: this.getTableData(),
          filename: 'excel',
          autoWidth: true
        })
        this.downloadLoading = false
      })
    },
    // 设置可展示列
    setVisible(columns) {
      const data = {}
      for (const v of columns.filter(v => v.visible === false)) {
        data[v.data] = false
      }
      this.innerColumnsVisible = data
      store.set(this.hash, data)
    },
    // 拷贝
    copy($event, header = true) {
      // 获取选中的tr
      const data = this.getSelectTrDataOrAll()
      const temp = []
      if (header) {
        const header = this.getTableHead()
        temp.push(header.join('\t'))
      }
      if (Array.isArray(data)) {
        data.forEach(v => {
          temp.push(v.join('\t'))
        })
      }
      import('@/utils/clipboard').then(clip => {
        clip.default(temp.join('\r\n'), $event)
      })
    },
    // 复选
    handleSelectionChange(rows) {
      this.checkData = rows
      this.$emit('selection-change', rows)
    },
    getSelected() {
      return this.checkData
    },
    // 标签也选择
    handleTabClick(tab, setModel = false) {
      let index = 0
      if (!Number.isInteger(tab)) {
        index = parseInt(tab.index)
      } else {
        index = tab
      }
      const tabItem = this.tabs[index]
      if (this.$_.isFunction(tabItem['callback'])) {
        tabItem['callback'](this.listQuery)
      }
      if (setModel) {
        this.activeName = 'tab-' + index
      }
      if (Array.isArray(tabItem['columns'])) {
        this.innerColumns = tabItem['columns']
      } else {
        this.innerColumns = this.columns
      }
      if (tabItem['url']) {
        this.tabUrl = tabItem['url']
      }
      this.getList()
    },
    // 获取全部数据
    getAllData() {
      return copy(this.list, true)
    },
    clear() {
      this.list = []
    }
  }
}
</script>
